/***************************************************************************
 * 文件名：SolutionUtil
 * 功能：
 * 说明：
 * -------------------------------------------------------------------------
 * 创建时间：2025/7/14 10:52:12
 * 创建人：葛浩
 * 邮箱： 2094733071@qq.com
 * =========================================================================
 *
 * 修改人：   
 * 修改时间：   
 * 修改说明：   
 ***************************************************************************/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ReferenceManagement
{
	public class SolutionUtil
	{
		#region 静态属性

		//internal class SolutionParser
		//Name: Microsoft.Build.Construction.SolutionParser
		//Assembly: Microsoft.Build, Version=4.0.0.0
		//解决方案属性
		private static Type s_SolutionParser;
		private static PropertyInfo s_SolutionParser_solutionReader;
		private static MethodInfo s_SolutionParser_parseSolution;
		private static PropertyInfo s_SolutionParser_projects;

		//项目属性
		private static Type s_ProjectInSolution;
		private static PropertyInfo s_ProjectInSolution_ProjectName;
		private static PropertyInfo s_ProjectInSolution_RelativePath;
		private static PropertyInfo s_ProjectInSolution_ProjectGuid;
		private static PropertyInfo s_ProjectInSolution_ProjectType;

		#endregion

		#region 方法

		/// <summary>
		/// 获取解决方案项目值
		/// 获取解决方案配置项
		/// </summary>
		/// <param name="solutionFileName"></param>
		public static List<SolutionProject> GetSolutionProjectList(string solutionFileName)
		{
			try
			{
				if (string.IsNullOrEmpty(solutionFileName))
				{
					throw new InvalidOperationException("");
				}

				s_SolutionParser = Type.GetType("Microsoft.Build.Construction.SolutionParser, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
				if (s_SolutionParser == null)
				{
					throw new InvalidOperationException("Can not find type 'Microsoft.Build.Construction.SolutionParser' are you missing a assembly reference to 'Microsoft.Build.dll'?");
				}

				s_SolutionParser_solutionReader = s_SolutionParser.GetProperty("SolutionReader", BindingFlags.NonPublic | BindingFlags.Instance);
				s_SolutionParser_projects = s_SolutionParser.GetProperty("Projects", BindingFlags.NonPublic | BindingFlags.Instance);
				s_SolutionParser_parseSolution = s_SolutionParser.GetMethod("ParseSolution", BindingFlags.NonPublic | BindingFlags.Instance);

				var solutionParser = s_SolutionParser.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic).First().Invoke(null);
				using (FileStream stream = new FileStream(solutionFileName, FileMode.Open, FileAccess.Read, FileShare.Read))
				{
					using (StreamReader reader = new StreamReader(stream))
					{
						s_SolutionParser_solutionReader.SetValue(solutionParser, reader, null);
						s_SolutionParser_parseSolution.Invoke(solutionParser, null);
					}
				}
				var projects = new List<SolutionProject>();
				var array = (Array)s_SolutionParser_projects.GetValue(solutionParser, null);
				for (int i = 0; i < array.Length; i++)
				{
					if (array.GetValue(i) == null)
					{
						continue;
					}

					//获取项目信息
					SolutionProject project = GetSolutionProjectInfo(array.GetValue(i));
					if (project == null)
					{
						continue;
					}
					projects.Add(project);
				}

				//获取项目信息的全路径名称
				DirectoryInfo solution = (new FileInfo(solutionFileName)).Directory;
				foreach (var project in projects.Where(temp => !temp.RelativePath.Equals(temp.ProjectName)))
				{
					project.FullName = Path.Combine(solution.FullName, project.RelativePath);
				}

				return projects;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return null;
			}
		}

		/// <summary>
		/// 获取具体项目的属性
		/// </summary>
		/// <param name="solutionProject"></param>
		/// <returns></returns>

		private static SolutionProject GetSolutionProjectInfo(object solutionProject)
		{
			try
			{
				if (solutionProject == null)
				{
					return null;
				}

				s_ProjectInSolution = Type.GetType("Microsoft.Build.Construction.ProjectInSolution, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", false, false);
				if (s_ProjectInSolution == null)
				{
					return null;
				}

				s_ProjectInSolution_ProjectName = s_ProjectInSolution.GetProperty("ProjectName", BindingFlags.NonPublic | BindingFlags.Instance);
				s_ProjectInSolution_RelativePath = s_ProjectInSolution.GetProperty("RelativePath", BindingFlags.NonPublic | BindingFlags.Instance);
				s_ProjectInSolution_ProjectGuid = s_ProjectInSolution.GetProperty("ProjectGuid", BindingFlags.NonPublic | BindingFlags.Instance);
				s_ProjectInSolution_ProjectType = s_ProjectInSolution.GetProperty("ProjectType", BindingFlags.NonPublic | BindingFlags.Instance);

				SolutionProject project = new SolutionProject()
				{
					ProjectName = s_ProjectInSolution_ProjectName.GetValue(solutionProject, null) as string,
					RelativePath = s_ProjectInSolution_RelativePath.GetValue(solutionProject, null) as string,
					ProjectGuid = s_ProjectInSolution_ProjectGuid.GetValue(solutionProject, null) as string,
					ProjectType = s_ProjectInSolution_ProjectType.GetValue(solutionProject, null).ToString(),
				};

				return project;
			}
			catch (Exception ex)
			{
				MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
				return null;
			}
		}
		#endregion
	}

	[DebuggerDisplay("{ProjectName}, {RelativePath}, {ProjectGuid}")]
	public class SolutionProject
	{
		/// <summary>
		/// 项目名称
		/// </summary>
		public string ProjectName { get; set; }

		/// <summary>
		/// 相对路径
		/// </summary>
		public string RelativePath { get; set; }

		/// <summary>
		/// 项目Guid
		/// </summary>
		public string ProjectGuid { get; set; }

		/// <summary>
		/// 项目类型
		/// </summary>
		public string ProjectType { get; set; }

		/// <summary>
		/// 全称
		/// </summary>
		public string FullName { set; get; }
	}
}
